package btanalyzer.db.analyzer;

import java.io.File;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;

import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
import org.gudy.azureus2.core3.torrent.TOTorrentFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import btanalyzer.db.dao.AnnounceUrlDao;
import btanalyzer.db.dao.MetadataDao;
import btanalyzer.db.dao.TorrentDao;
import btanalyzer.db.model.Metadata;
import btanalyzer.db.model.ResourceFile;
import btanalyzer.db.model.Torrent;

@Component
public class MetadataAnalyzerByTorrentIdImpl implements MetadataAnalyzerByTorrentId {
	
	private static final Logger log = LoggerFactory.getLogger(MetadataAnalyzerByTorrentIdImpl.class);
	private static long notFoundCnt = 0L;
	private static long renamedCnt = 0L;
	
	
	@Override
	@Transactional
	public void analyzeMatadata(long torrentId, String[] badSuffs) {
		Torrent t = getTorrentDao().selectById(torrentId);
		TOTorrent toTorrent = null;
		try {
			File f = new File(t.getMetadataFilePath());
			for (String suff : badSuffs) {
				if (f.getName().endsWith(suff)) {
					File nf = new File(f.getParent() + "/___" + f.getName());
					f.renameTo(nf);
					System.out.println("Rendamed: " + renamedCnt ++);
//					System.out.println("Renamed " + f.getPath() + " to " + 
//							nf.getPath()) ;
					return;
				}
			}
			if (!f.exists()) { 
				System.out.println("NotFound:" + notFoundCnt++);
//				System.out.println("nie ma pliku " + f.getPath()); 
				return; 
			}
			System.out.println(f.getAbsolutePath());
			toTorrent = TOTorrentFactory.deserialiseFromBEncodedInputStream(new FileInputStream(f));
		} catch (Exception e) {
			String errMsg = "Exception during reading metadata file=" + t.getMetadataFilePath();
			log.error(errMsg, e);
//			throw new RuntimeException(errMsg, e);
			return;
		}
		
		
		Metadata m = new Metadata();
		t.setMetadata(m);
		m.setTorrnet(t);
		
		try {
			m.setName(new String(toTorrent.getName(), "UTF8"));
		} catch (UnsupportedEncodingException e) {
			m.setName(toTorrent.getName().toString());
			log.warn("could not encode " + toTorrent.getName() + 
					", writing toString() result.", e);
		}
		m.setSizeInBytes(toTorrent.getSize());
		m.setAnnounceUrl(toTorrent.getAnnounceURL().toString());
		m.setPieceQuantity(toTorrent.getNumberOfPieces());
		m.setPieceSizeInBytes(toTorrent.getPieceLength());
		m.setCreationDate(new Date(toTorrent.getCreationDate() * 1000));
		m.setDownloadedDate(new Date(new File(t.getMetadataFilePath()).lastModified()));
		
//		int fileOrder = 0;
//		for (TOTorrentFile toTorrentFile : toTorrent.getFiles()) {
//			ResourceFile rf = new ResourceFile();
//			rf.setRelativePath(toTorrentFile.getRelativePath());
//			rf.setOrderNumber(fileOrder);
//			rf.setMetadata(m);
//			m.getResourceFiles().add(rf);
//		}
		
//		int announceUrlOrder = 0;
//		for (TOTorrentAnnounceURLSet announceUrlSet : toTorrent.getAnnounceURLGroup().
//				getAnnounceURLSets()) {
//			for (URL annUrl : announceUrlSet.getAnnounceURLs()) {
//				AnnounceUrl announceUrl = null;
//				if (announceUrlDao.countByUrl(annUrl.toString()) == 0L) {
//					announceUrl = new AnnounceUrl();
//					announceUrl.setUrl(annUrl.toString());
//					announceUrl = announceUrlDao.save(announceUrl);
//				} else {
//					announceUrl = announceUrlDao.selectByUrl(annUrl.toString());
//				}
//				MetadataAnnounceUrl metadataAnnounceUrl = new MetadataAnnounceUrl();
//				metadataAnnounceUrl.setAnnounceUrl(announceUrl);
//				metadataAnnounceUrl.setMetadata(m);
//				metadataAnnounceUrl.setOrderNumber(announceUrlOrder++);
//				m.getMetadataAnnounceUrls().add(metadataAnnounceUrl);
//			}
//		}
		
		int resourceFileOrder = 0;
		for (TOTorrentFile toTorrentFile : toTorrent.getFiles()) {
			ResourceFile resourceFile = new ResourceFile();
			resourceFile.setRelativePath(toTorrentFile.getRelativePath());
			resourceFile.setOrderNumber(resourceFileOrder++);
			resourceFile.setMetadata(m);
			m.getResourceFiles().add(resourceFile);
		}
		
		System.out.println("persisting metadata=" + m);
		getTorrentDao().save(t);
		getTorrentDao().flush();
	}
	
	@Autowired
	private TorrentDao torrentDao;
	public void setTorrentDao(TorrentDao torrentDao) {
		this.torrentDao = torrentDao;
	}
	public TorrentDao getTorrentDao() {
		return torrentDao;
	}
	
	@Autowired
	AnnounceUrlDao announceUrlDao;
	public void setAnnounceUrlDao(AnnounceUrlDao announceUrlDao) {
		this.announceUrlDao = announceUrlDao;
	}
	public AnnounceUrlDao getAnnounceUrlDao() {
		return announceUrlDao;
	}
	
	@Autowired
	MetadataDao metadataDao;
	public void setMetadataDao(MetadataDao metadataDao) {
		this.metadataDao = metadataDao;
	}
	public MetadataDao getMetadataDao() {
		return metadataDao;
	}
}
